package hn.cch.spring.boot.advice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import hn.cch.spring.boot.filter.HandlerInterceptorImpl;
import hn.cch.spring.boot.message.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;


@ControllerAdvice
@ConditionalOnBean(value = {HandlerInterceptorImpl.class})
public class ResponseBodyAdviceImpl implements ResponseBodyAdvice<Object> {

    private final static Logger logger = LoggerFactory.getLogger(ResponseBodyAdviceImpl.class);

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterClass) {
        logger.info("supports");
        return true;
    }


    @Override
    public Object beforeBodyWrite(@Nullable Object responseObject, MethodParameter methodParameter,
                                  MediaType mediaType, Class<? extends HttpMessageConverter<?>> converterClass,
                                  ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        logger.info("beforeBodyWrite");
        Object buffer = null;
        try {
            Response<Object> response = Response.success(responseObject);
            if (responseObject instanceof String || converterClass.isAssignableFrom(StringHttpMessageConverter.class)) {
                buffer = toJson(response);
            } else if (responseObject instanceof Response) {
                buffer = responseObject;
            } else {
                buffer = response;
            }
        } catch (Exception e) {
            buffer = Response.failure(e.getMessage());
        }
        return buffer;
    }

    public static String toJson(Object object) throws JsonProcessingException {
        // 字符串不处理
        if (object instanceof String) {
            return (String) object;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(object);
    }

}